package com.maxmlr.framework.mvc;

import lombok.AllArgsConstructor;
import lombok.Data;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

/**
 * @ClassName HandlerAdapter
 * @Description TODO
 * @Author maxiao
 * @Date 2020/3/18 上午10:58
 * @Version V1.0
 */
@Data
@AllArgsConstructor
public class HandlerAdapter {

    private Map<String, Integer> paramMapping;

    /**
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, HandlerMapping handler) throws Exception {
        Method method = handler.getMethod();
        Class<?>[] parameterTypes = method.getParameterTypes();
        Object[] args = new Object[parameterTypes.length];
        Map<String, String[]> parameterMap = request.getParameterMap();
        for (String paramName : parameterMap.keySet()) {
            String[] strings = parameterMap.get(paramName);
            String value = Arrays.toString(strings).replaceAll("\\[|\\]", "")
                    .replaceAll("\\s", "");
            if (!this.paramMapping.containsKey(paramName)) {
                continue;
            }
            Integer index = paramMapping.get(paramName);
            args[index] = caseStringValue(value, parameterTypes[index]);
        }

        if (this.paramMapping.containsKey(HttpServletRequest.class.getName())) {
            args[paramMapping.get(HttpServletRequest.class.getName())] = request;
        }

        if (this.paramMapping.containsKey(HttpServletResponse.class.getName())) {
            args[paramMapping.get(HttpServletResponse.class.getName())] = request;
        }

        //执行
        Object result = method.invoke(handler.getController(), args);

        if (method.getReturnType() == ModelAndView.class) {
            return (ModelAndView) result;
        } else {
            return null;
        }

    }

    private Object caseStringValue(String value, Class<?> clazz) {
        if (clazz == String.class) {
            return value;
        } else if (clazz == Integer.class) {
            return Integer.valueOf(value);
        } else if (clazz == int.class) {
            return Integer.valueOf(value).intValue();
        } else {
            return null;
        }
    }

}
